package com.iwayin.core.bo;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.mail.internet.MimeMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.iwayin.core.common.Constants;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

/**
 * 发送邮件工具类
 * @author harry
 *
 */
public class EmailServiceUtil {
	
	//模板缓存
	private static LoadingCache<String, Template> templateCache = CacheBuilder.newBuilder()
			.expireAfterAccess(600, TimeUnit.SECONDS).maximumSize(20)
			.build(new CacheLoader<String, Template>(){
				@Override
				public Template load(String key) throws Exception {
					Configuration cfg = new Configuration();
					URL url = EmailServiceUtil.class.getClassLoader().getResource("template");
					File file = new File(url.getFile());
					try {
						cfg.setDirectoryForTemplateLoading(file);
					} catch (IOException e) {
						e.printStackTrace();
					}
					// 设置对象的包装器
					cfg.setObjectWrapper(new DefaultObjectWrapper());
					// 设置异常处理器
					// 这样的话就可以${a.b.c.d}即使没有属性也不会出错
					cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
					return cfg.getTemplate(key);
				}
			});
	/**
	 * 发送关注邮件
	 * @param userId 关注者
	 * @param followId 被关注者 邮件接收Id
	 */
	public static void sendFollowEmail(String receiver,
			Map<String, Object> params) {
		try {
			params.put("infoMsg", "开始关注了你的问问");
			params.put("backMsg", "看看你的新粉丝");
			params.put("warnMsg1", " 如果你无法看到此邮件, 请登录");
			params.put("warnMsg2", "浏览你的动态!");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("followEmail.ftl"), params);
			send(receiver, params.get("nickname") + "关注了你的问问", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 发送添加答案邮件
	 * @param receiver
	 * @param params
	 */
	public static void sendAnswerEmail(String receiver,
			Map<String, Object> params) {
		try {
			params.put("qinfo1", "对问问");
			params.put("qinfo2", "添加了答案");
			params.put("msg", "查看投票进度");
			params.put("warnMsg1", " 如果你无法看到此邮件, 请登录");
			params.put("warnMsg2", "浏览你的动态!");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("addAnswer.ftl"), params);
			send(receiver, params.get("nickname") + "对你的问问添加了答案", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 发送评论邮件
	 * @param receiver
	 * @param params
	 */
	public static void sendCommentEmail(String receiver,
			Map<String, Object> params) {
		try {
			params.put("qinfo1", "对问问");
			params.put("qinfo2", "进行了评论");
			params.put("msg", "立即查看");
			params.put("warnMsg1", " 如果你无法看到此邮件, 请登录");
			params.put("warnMsg2", "浏览你的动态!");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("addAnswer.ftl"), params);
			send(receiver, params.get("nickname") + "对你的问问进行了评论", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 投票发送邮件
	 * @param receiver
	 * @param params
	 */
	public static void sendVoteEmail(String receiver,
			Map<String, Object> params) {
		try {
			params.put("qinfo1", "对问问");
			params.put("qinfo2", "进行了投票");
			params.put("msg", "查看投票进度");
			params.put("warnMsg1", " 如果你无法看到此邮件, 请登录");
			params.put("warnMsg2", "浏览你的动态!");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("addAnswer.ftl"), params);
			send(receiver, params.get("nickname") + "对你的问问进行了投票", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 喜欢发送邮件
	 * @param receiver
	 * @param params
	 */
	public static void sendLikerEmail(String receiver,
			Map<String, Object> params) {
		try {
			params.put("qinfo1", "喜欢了你的问问");
			params.put("msg", "查看");
			params.put("warnMsg1", " 如果你无法看到此邮件, 请登录");
			params.put("warnMsg2", "浏览你的动态!");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("addLike.ftl"), params);
			send(receiver, params.get("likerName") + "喜欢了你的问问", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 
	 * @param receiver
	 * @param params
	 */
	public static void sendTopVote5Email(String receiver,
			Map<String, Object> params) {
		try {
			params.put("info", "今天投票最热烈的问问!");
			params.put("msg", "立即投票!");
			params.put("warnMsg1", " 如果你无法看到此邮件,");
			params.put("warnMsg2", "点击这里");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("topVote5.ftl"), params);
			send(receiver, params.get("askInfo") + " | 今日热门问问", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @param receiver
	 * @param params
	 */
	public static void sendTopLike5Email(String receiver,
			Map<String, Object> params) {
		try {
			params.put("info", "今天最受欢迎的问问!");
			params.put("msg", "立即查看!");
			params.put("warnMsg1", " 如果你无法看到此邮件,");
			params.put("warnMsg2", "点击这里");
			String content = FreeMarkerTemplateUtils.processTemplateIntoString(
					templateCache.getUnchecked("topVote5.ftl"), params);
			send(receiver, params.get("askInfo") + " | 今日热门问问", content);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	

	/**
	 * 发送邮件
	 * 
	 * @param receivers
	 *            收件人
	 * @param subject
	 *            标题
	 * @param mailContent
	 *            邮件内容
	 * @param mimetype
	 *            内容类型 默认为text/plain,如果要发送HTML内容,应设置为text/html
	 */
	public static boolean send(String receivers, String subject, String mailContent) {
		new Sender(receivers, subject, mailContent).start();
		return true;
	}
	/**
	 * 多邮件发送
	 * @param receivers
	 * @param subject
	 * @param mailContent
	 * @param mimetype
	 * @return
	 */
	public static boolean sendList(String[] receivers, String subject,
			String mailContent) {
		for(int i = 0;i < receivers.length;i++){
			send(receivers[i],subject, mailContent);
		}
		return true;
	}
	
	/**
	 * 发送邮件
	 * 
	 * @param receivers
	 *            收件人
	 * @param subject
	 *            标题
	 * @param mailContent
	 *            邮件内容
	 * @param mimetype
	 *            内容类型 默认为text/plain,如果要发送HTML内容,应设置为text/html
	 */
	public static boolean synchSend(String receivers, String subject,
			String mailContent, String mimetype) {
		try {
			JavaMailSenderImpl sender = new JavaMailSenderImpl();
			Properties props = new Properties();
			props.put("mail.smtps.auth", "true"); // Smtp服务器地址
			props.put("mail.smtp.starttls.enable", "true"); // 需要校验
			sender.setJavaMailProperties(props);
			sender.setProtocol("smtps");
			sender.setPort(465);
			sender.setHost(Constants.SYSTEM_EMAIL_HOST);
			sender.setUsername(Constants.SYSTEM_EMAIL_USERNAME);
			sender.setPassword(Constants.SYSTEM_EMAIL_PASSWORD);
			MimeMessage mimeMessage = sender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,
					"utf-8");
			helper.setTo(receivers);
			helper.setFrom(Constants.SYSTEM_EMAIL_USERNAME,Constants.SYSTEM_EMAIL_SHOW_NAME);
			helper.setSubject(subject);
			helper.setText(mailContent, true);
			sender.send(mimeMessage);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

}

/**
 * 线程类
 */
class Sender extends Thread {
	protected Log loger = LogFactory.getLog(this.getClass());
	private String receivers;
	private String subject;
	private String mailContent;

	public Sender(String receivers, String subject, String mailContent) {
		this.mailContent = mailContent;
		this.receivers = receivers;
		this.subject = subject;
	}

	@Override
	public void run() {
		try {
			JavaMailSenderImpl sender = new JavaMailSenderImpl();
			Properties props = new Properties();
			props.put("mail.smtps.auth", "true"); // Smtp服务器地址
			props.put("mail.smtp.starttls.enable", "true"); // 需要校验
			sender.setJavaMailProperties(props);
			sender.setProtocol("smtps");
			sender.setPort(465);
			sender.setHost(Constants.SYSTEM_EMAIL_HOST);
			sender.setUsername(Constants.SYSTEM_EMAIL_USERNAME);
			sender.setPassword(Constants.SYSTEM_EMAIL_PASSWORD);
			MimeMessage mimeMessage = sender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,
					"utf-8");
			helper.setTo(receivers);
			helper.setFrom(Constants.SYSTEM_EMAIL_USERNAME,Constants.SYSTEM_EMAIL_SHOW_NAME);
			helper.setSubject(subject);
			helper.setText(mailContent, true);
			sender.send(mimeMessage);
		} catch (Exception e) {
			loger.error("send email fail", e);
		}
	}
}
